use Test::More tests => 128;
#use Test::More qw(no_plan);

use Firepear::Carrot::Lexer;

BEGIN {
use_ok( 'Firepear::Carrot::Handler::Trigger' );
}

my $mu = ['[',']',';',"'",'-'];

my $h = Firepear::Carrot::Handler::Trigger->new( mu => $mu );

isa_ok ($h, 'Firepear::Carrot::Handler::Trigger');

is ($h->{mu}{o}, '\[\[', 'open');
is ($h->{mu}{c}, '\]\]', 'close');
is ($h->{mu}{r}, '\;\;\;', 'rem');
is ($h->{mu}{s}, '\;', 'separator');
is ($h->{mu}{q}, "\\'", 'quote');
is ($h->{mu}{z}{o}, '\[', 'rawopen');
is ($h->{mu}{z}{c}, '\]', 'rawclose');

######################################################## 000 - Normal operation
is ($h->status, 0, 'normal ops - 0');

##################################################################### 'handles'
is ($h->handles('[[document'), 1, 'Yes, we handle triggers');
is ($h->handles('[[[data'), 0, 'No, we dont handle verbatim chunks');
is ($h->handles('[section'), 0, 'No, we dont handle tags');
is ($h->handles('text'), 0, 'No, we dont handle raw text');
#is ($h->handles('bleh]]'), 1, 'Yes, we handle trigger terminals');
is ($h->handles('bleh]]'), 0, 'No,this counts as text now');
is ($h->handles(']]'), 1, 'Yes, we handle trigger terminals');
is ($h->handles(']]]'), 1, 'We will partially consume verbatim terminals');
is ($h->handles('bleh]'), 0, 'No, we dont handle tag terminals');

################################################### 001 - Complete node parsing
my $t = "[[document title;Foobar]]\nthis is a test";
my $l = Firepear::Carrot::Lexer->new( files => [ {scalar => 1, text => $t} ] );
my $token = $l->fetch; # prime
$h->status(0);
is ($h->handles($token), 1, 'we should handle this');
is ($h->status, 0, 'normal ops handler');
is ($l->status, 0, 'normal ops lexer');
my $node = $h->lex($l);
is ($h->status, 1, 'node complete');
is ($l->status, 0, 'normal ops lexer');
is (defined $node, 1);
is (ref $node, 'HASH', 'should be a hashref');
is ($node->{element}, 'document');
is ($node->{refid}, undef);
is ($node->{type}, 'TRIGGER');
is ($node->{finfo}[0], 1, 'file number');
is ($node->{finfo}[1], 1, 'line in file');
is (ref $node->{attrs}, 'ARRAY');
is ($node->{attrs}[0], 'title');
is ($node->{attrs}[1], 'Foobar');
is ($l->current, ']]', 'Lexer in expected state');
is ($l->fetch, "\n", 'Lexer in expected state');
is ($l->fetch, "this", 'Lexer in expected state');

$t = "[[document        title;'Foo bar'  ]]\nthis is a test";
$l = Firepear::Carrot::Lexer->new( files => [ {scalar => 1, text => $t} ] );
$token = $l->fetch; # prime
$h->status(0);
is ($h->handles($token), 1, 'we should handle this');
$node = $h->lex($l);
is ($h->status, 1, 'normal ops');
is ($l->status, 0, 'normal ops lexer');
is (ref $node, 'HASH', 'should be a hashref');
is ($node->{element}, 'document');
is ($node->{refid}, undef);
is ($node->{type}, 'TRIGGER');
is ($node->{finfo}[0], 1, 'file number');
is ($node->{finfo}[1], 1, 'line in file');
is (ref $node->{attrs}, 'ARRAY');
is ($node->{attrs}[0], 'title');
is ($node->{attrs}[1], 'Foo bar');
is ($l->fetch, "\n");
is ($l->fetch, 'this');

$t = "[[document title;Foobar author;'mdxi mdxi']]";
$l = Firepear::Carrot::Lexer->new( files => [ {scalar => 1, text => $t} ] );
$l->fetch; # prime
$h->status(0);
$node = $h->lex($l);
is ($h->status, 1, 'node processed completely - 1'); # multiple attributes
is ($l->status, 99, 'EOD');
is (ref $node, 'HASH', 'should be a hashref');
is ($node->{element}, 'document');
is ($node->{refid}, undef);
is ($node->{attrs}[0], 'title');
is ($node->{attrs}[1], 'Foobar');
is ($node->{attrs}[2], 'author');
is ($node->{attrs}[3], 'mdxi mdxi');

$t = "[[document;quux ;;; multiline with comments
        title;Foobar date;now;;;multiple comments, actually
        author;'Shawn Boyette's Dog, Esq.']]";
$l = Firepear::Carrot::Lexer->new( files => [ {scalar => 1, text => $t} ] );
$l->fetch; # prime
$h->status(0);
$node = $h->lex($l);
is ($h->status, 1, 'node processed completely - 1');
is ($l->status, 99, 'EOD');
is ($l->current, ']]', 'terminator');
is (ref $node, 'HASH', 'should be a hashref');
is ($node->{element}, 'document');
is ($node->{refid}, 'quux');
is ($node->{attrs}[0], 'title');
is ($node->{attrs}[1], 'Foobar');
is ($node->{attrs}[2], 'date');
is ($node->{attrs}[3], 'now');
is ($node->{attrs}[4], 'author');
is ($node->{attrs}[5], "Shawn Boyette's Dog, Esq.");

######################################################### 002 - Partial Parsing
$t = "[[foo bar;quux bar2;'this is a test' content]]";
$l = Firepear::Carrot::Lexer->new( files => [ {scalar => 1, text => $t} ] );
$l->fetch; # prime
$h->status(0);
$node = $h->lex($l);
is ($h->status, 2, 'node processed partially - 2');
is ($l->status, 1, 'EOD');
is (ref $node, 'HASH', 'should be a hashref');
is ($node->{element}, 'foo');
is ($node->{refid}, undef);
is ($node->{attrs}[0], 'bar');
is ($node->{attrs}[1], 'quux');
is ($node->{attrs}[2], 'bar2');
is ($node->{attrs}[3], 'this is a test');
is ($l->current, ' ');
is ($l->fetch, 'content]]');

$t = "[[foo bar;quux bar2;'this is a test' content starts here ]]";
$l = Firepear::Carrot::Lexer->new( files => [ {scalar => 1, text => $t} ] );
$l->fetch; # prime
$h->status(0);
$node = $h->lex($l);
is ($l->status, 0, 'nominal');
is ($h->status, 2, 'node processed partially - 2');
is (ref $node, 'HASH', 'should be a hashref');
is ($node->{element}, 'foo');
is ($node->{refid}, undef);
is ($node->{attrs}[0], 'bar');
is ($node->{attrs}[1], 'quux');
is ($node->{attrs}[2], 'bar2');
is ($node->{attrs}[3], 'this is a test');
is ($l->current, ' ');
is ($l->fetch, 'content');

$t = "[[foo bar;quux bar2;'this is a test'\n[[[verbatim blah blah\n]]]\n ]]";
$l = Firepear::Carrot::Lexer->new( files => [ {scalar => 1, text => $t} ] );
$l->fetch; # prime
$h->status(0);
$node = $h->lex($l);
is (ref $node, 'HASH', 'should be a hashref');
is ($node->{element}, 'foo');
is ($node->{refid}, undef);
is ($node->{attrs}[0], 'bar');
is ($node->{attrs}[1], 'quux');
is ($node->{attrs}[2], 'bar2');
is ($node->{attrs}[3], 'this is a test');
is ($h->status, 2, 'node processed partially - 2');
is ($l->current, "\n");
is ($l->fetch, '[[[verbatim');

################################################################ 003 - Terminal
$t = "]]";
$l = Firepear::Carrot::Lexer->new( files => [ {scalar => 1, text => $t} ] );
$l->fetch; # prime
$h->status(0);
$node = $h->lex($l);
is ($node, undef);
is ($h->status, 3, 'markup terminal found');

$t = "]] foo";
$l = Firepear::Carrot::Lexer->new( files => [ {scalar => 1, text => $t} ] );
$l->fetch; # prime
$h->status(0);
$node = $h->lex($l);
is ($node, undef);
is ($h->status, 201, 'illegal terminal location');

####################################################### 100 - Null element name
$t = "[[ document foo;bar]]";
$l = Firepear::Carrot::Lexer->new( files => [ {scalar => 1, text => $t} ] );
$l->fetch; # prime
$h->status(0);
$node = $h->lex($l);
is ($node, undef);
is ($h->status, 100);

$t = "[[;quux foo;bar]]";
$l = Firepear::Carrot::Lexer->new( files => [ {scalar => 1, text => $t} ] );
$l->fetch; # prime
$h->status(0);
$node = $h->lex($l);
is ($node, undef);
is ($h->status, 100);

################################################ 101 - Indicated but null refid
$t = "[[document; foo;bar]]";
$l = Firepear::Carrot::Lexer->new( files => [ {scalar => 1, text => $t} ] );
$l->fetch; # prime
$h->status(0);
$node = $h->lex($l);
is ($node, undef);
is ($h->status, 101);

##################################################### 102 - Null argument value
$t = "name;";
$l = Firepear::Carrot::Lexer->new( files => [ {scalar => 1, text => $t} ] );
$l->fetch; # prime
is ($l->current, 'name;', 'lexer as expected');
$h->status(0);
$h->buildattr($l);
is ($h->status, 102);


###################################################### 103 - Null argument name
$t = ";value";
$l = Firepear::Carrot::Lexer->new( files => [ {scalar => 1, text => $t} ] );
$l->fetch; # prime
$h->status(0);
$h->buildattr($l);
is ($h->status, 103);


################################################## 104 - Quoted attrib mismatch
$t = "[[document f;b b;'quux]]";
$l = Firepear::Carrot::Lexer->new( files => [ {scalar => 1, text => $t} ] );
$l->fetch; # prime
$h->status(0);
$node = $h->lex($l);
is ($l->status, 99);
is ($l->current, "]]");
is ($node, undef);
is ($h->status, 104);


$t = "[[document f;b b;'quux baz]]";
$l = Firepear::Carrot::Lexer->new( files => [ {scalar => 1, text => $t} ] );
$l->fetch; # prime
$h->status(0);
$node = $h->lex($l);
is ($node, undef);
is ($h->status, 104);


######################################## 200 - Invalid trigger opening position
$t = "foo bar [[quxx baz;alpha]]";
$l = Firepear::Carrot::Lexer->new( files => [ {scalar => 1, text => $t} ] );
$l->fetch; $l->fetch; $l->fetch; # prime
$h->status(0);
$node = $h->lex($l);
is ($node, undef);
is ($h->status, 200);

######################################## 201 - Invalid trigger closing position
$t = "[[quxx baz;alpha]] foo";
$l = Firepear::Carrot::Lexer->new( files => [ {scalar => 1, text => $t} ] );
$l->fetch; # prime
$h->status(0);
$node = $h->lex($l);
is ($node, undef);
is ($h->status, 201);

$t = "[[quxx baz;alpha]]foo";
$l = Firepear::Carrot::Lexer->new( files => [ {scalar => 1, text => $t} ] );
$l->fetch; # prime
$h->status(0);
$node = $h->lex($l);
is ($node, undef);
is ($h->status, 201);
